package com.wcy.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wcy.annotation.aop.PreAuth;
import com.wcy.entity.UserRating;
import com.wcy.entity.queryVo.QueryConvertor;
import com.wcy.entity.result.RatingResult;
import com.wcy.service.IUserRatingService;
import com.wcy.util.JwtTokenUtil;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;

@RestController
@RequestMapping("/userRating")
public class UserRatingController {

    @Autowired
    private IUserRatingService userRatingService;
    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @PreAuth("RATING:QUERY")
    @GetMapping("/page")
    @SentinelResource(value = "#root.targetClass + '.' + #root.methodName")
    public ResponseEntity<Page<UserRating>> getPage(@RequestParam(defaultValue = "1") int pageNum,
                                                    @RequestParam(defaultValue = "10") int pageSize,
                                                    HttpServletRequest request) {
        String queryData = request.getHeader("X-Query-Data");
        QueryWrapper wrapper = new QueryConvertor(queryData).convert(true);
        Page<UserRating> page = userRatingService.page(new Page<>(pageNum, pageSize),  wrapper);
        return ResponseEntity.ok(page);
    }

//    @PreAuth("RATING:QUERY")
    @GetMapping("/list")
    @SentinelResource(value = "#root.targetClass + '.' + #root.methodName")
    public ResponseEntity<List<UserRating>> getList(HttpServletRequest request) {
        String queryData = request.getHeader("X-Query-Data");
        QueryWrapper wrapper = new QueryConvertor(queryData).convert(true);
        List<UserRating> list = userRatingService.list(wrapper);
        return ResponseEntity.ok(list);
    }

    @PreAuth("RATING:ADD")
    @PostMapping("/add")
    @SentinelResource(value = "#root.targetClass + '.' + #root.methodName")
    public ResponseEntity<Void> add(@RequestBody UserRating userRating) {
        userRating.setRatedAt(LocalDateTime.now());
        userRatingService.save(userRating);
        return ResponseEntity.ok().build();
    }

    @PreAuth("RATING:ALTER")
    @PutMapping("/update")
    @SentinelResource(value = "#root.targetClass + '.' + #root.methodName")
    public ResponseEntity<Void> update(@RequestBody UserRating userRating) {
        userRatingService.updateById(userRating);
        return ResponseEntity.ok().build();
    }

    @PreAuth("RATING:DELETE")
    @DeleteMapping("/delete/{id}")
    @SentinelResource(value = "#root.targetClass + '.' + #root.methodName")
    public ResponseEntity<Void> delete(@PathVariable Integer id) {
        userRatingService.removeById(id);
        return ResponseEntity.ok().build();
    }

    @GetMapping("/resource/{id}")
    @SentinelResource(value = "#root.targetClass + '.' + #root.methodName")
    ResponseEntity<RatingResult> getByResourceId(@PathVariable("id") Integer id) {
        List<UserRating> list = userRatingService.list(new QueryWrapper<UserRating>().eq("resource_id", id));
        return ResponseEntity.ok(new RatingResult(list.size(), list.stream().mapToDouble(UserRating::getRatingValue).average().orElse(0)));
    }

    @GetMapping("/resource/{id}/hasRated")
    @SentinelResource(value = "#root.targetClass + '.' + #root.methodName")
    ResponseEntity<Boolean> getHasRated(@PathVariable("id") Integer id,HttpServletRequest request) {
        Integer userId = jwtTokenUtil.getUserIdFromToken(jwtTokenUtil.getToken(request));
        return ResponseEntity.ok(userRatingService.exists(new QueryWrapper<UserRating>().eq("user_id",userId).eq("resource_id", id)));
    }

    @PostMapping("/resource/{id}/send")
    @SentinelResource(value = "#root.targetClass + '.' + #root.methodName")
    ResponseEntity<Boolean> sendRating(@PathVariable("id") Integer id, @RequestBody UserRating rating, HttpServletRequest request) {
        Integer userId = jwtTokenUtil.getUserIdFromToken(jwtTokenUtil.getToken(request));
        rating.setUserId(userId);
        rating.setResourceId(id);
        rating.setRatedAt(LocalDateTime.now());
        userRatingService.save(rating);
        return ResponseEntity.ok().build();
    }
}